#pragma once

#include <iostream>
#include <memory>
#include "Socket.hpp"
#include "Connection.hpp"
#include "Common.hpp"
#include "Epoller.hpp"
#include "Channel.hpp"
#include "Reactor.hpp"

using namespace SocketModule;

class Listener : public Connection
{
public:
    Listener(int port = 8080)
        : _port(port), _listensock(std::make_unique<TcpSocket>())
    {
        _listensock->BuildListenSocket(_port);
        SetEvent(EPOLLIN | EPOLLET); // 让关心事件通过ET模式运行
        SetFd(_listensock->Fd());
        SetNonBlock(_listensock->Fd()); // 通过fcntl获取并设置文件描述符的非阻塞状态
    }

    void Recver()
    {
        // 对于listener来说，recv就是accept
        // std::cout << "enter listerModule Recver" << std::endl;
        // 获取链接时，可能不只有一个链接，一次把所有链接都获取上来，通过ET模式工作
        InitAddr client;
        while (true)
        {
            int sockfd = _listensock->Accept(client);
            if (sockfd == -1)
            {
                break;
            }
            else if (sockfd == -2)
            {
                continue;
            }
            else if (sockfd == -3)
            {
                break;
            }
            else
            {
                //获取到正确的链接，并将这个链接添加到tcpserver的哈希管理表中
                std::shared_ptr<Connection> conn = std::make_shared<Channel>(sockfd, client);
                conn->SetEvent(EPOLLIN | EPOLLET);
                GetOwner()->AddConnection(conn);
            }
        }
    }

    void Sender()
    {
        std::cout << "Listener sender" << std::endl;
    }

    void Excepter()
    {
        std::cout << "Excepter sender" << std::endl;
    }

    ~Listener()
    {
    }

private:
    int _port;
    std::unique_ptr<Socket> _listensock;
};